package com.ys.service.storage.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ys.entity.storage.*;
import com.ys.enume.storage.TccLogisticsApiLogEnum;
import com.ys.enume.storage.TccLogisticsComprehensiveEnum;
import com.ys.mapper.storage.StorageMapper;
import com.ys.mapper.storage.TccLogisticsApiLogMapper;
import com.ys.service.storage.TccLogisticsApiService;
import com.ys.service.storage.TccLogisticsComprehensiveOrderService;
import com.ys.util.AESUtil;
import com.ys.util.ApiHttpUtils;
import com.ys.util.ToolUtil;
import com.ys.vo.R;
import org.jboss.logging.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author: fxz
 * @CreateTime: 2025-03-13
 * @Description: 物流服务商api实现类
 * @Version: 1.0
 */
@Service("tccLogisticsApiService")
public class TccLogisticsApiServiceImpl implements TccLogisticsApiService {

    private static final Logger logger = Logger.getLogger(TccLogisticsApiServiceImpl.class);

    @Autowired
    private TccLogisticsApiLogMapper tccLogisticsApiLogMapper;

    @Autowired
    private TccLogisticsComprehensiveOrderService tccLogisticsComprehensiveOrderService;

    @Autowired
    private StorageMapper storageMapper;

    /**
     * 获取正式费用查询接口
     * @return
     */
    @Override
    public R getPrice(TccLogisticsComprehensive tccLogisticsComprehensive) {
        try {
            //物流渠道
            TccLogisticsChannelMaint tccLogisticsChannelMaint = new TccLogisticsChannelMaint().setId(tccLogisticsComprehensive.getLogChannelId()).queryFirst();
            //查询物流服务商
            TccLogisticsServiceProvider tccLogisticsServiceProvider = new TccLogisticsServiceProvider().setProviderBid(tccLogisticsChannelMaint.getProviderCode()).queryFirst();
            if (tccLogisticsServiceProvider == null || tccLogisticsServiceProvider.getAppkey() == null || tccLogisticsServiceProvider.getAppkey().equals("")){
                logger.error("该物流服务商"+tccLogisticsServiceProvider.getName()+"未链接api，无法api下单，请知晓");
                return R.error("该物流服务商，无法api下单，请知晓。");
            }

            JSONObject jsonObject = new JSONObject();

            jsonObject.put("PACKNO",tccLogisticsComprehensive.getLogInvoiceNo());//运单号-发票号
            jsonObject.put("TYPENO","ZS");

            JSONObject resultJO = getResult(jsonObject,TccLogisticsApiLogEnum.TypeNo.GETPRICE.value,tccLogisticsServiceProvider,tccLogisticsComprehensive);


            if (resultJO.get("code").equals(0)){
                logger.error("获取正式费用查询接口失败,失败原因如下:" + resultJO.get("msg").toString());
                return R.error(resultJO.get("msg").toString());
            }else {
                logger.info("获取正式费用查询接口成功!");
                return R.ok(resultJO);
            }

        }catch (Exception e){
            logger.error("获取正式费用查询接口失败,失败原因如下:" + e.getMessage());
            return R.error(e.getMessage());
        }
    }

    /**
     * 订单信息获取接口
     * @return
     */
    @Override
    public R getorder(String logInvoiceNo) {
        try {
            //物流渠道
            TccLogisticsChannelDetail tccLogisticsChannelDetail = new TccLogisticsChannelDetail().setLogInvoiceNo(logInvoiceNo).queryFirst();

            //查询物流服务商
            TccLogisticsServiceProvider tccLogisticsServiceProvider = new TccLogisticsServiceProvider().setProviderBid(tccLogisticsChannelDetail.getProviderCode()).queryFirst();
            if (tccLogisticsServiceProvider == null || tccLogisticsServiceProvider.getAppkey() == null || tccLogisticsServiceProvider.getAppkey().equals("")){
                return R.error("该物流渠道未链接api，无法api下单，请知晓。");
            }
            JSONObject jsonObject = new JSONObject();

            jsonObject.put("PACKNO",logInvoiceNo);//运单号

            TccLogisticsComprehensive tccLogisticsComprehensive = new TccLogisticsComprehensive().setLogInvoiceNo(logInvoiceNo).queryFirst();

            JSONObject resultJO = getResult(jsonObject,TccLogisticsApiLogEnum.TypeNo.GETORDER.value,tccLogisticsServiceProvider,tccLogisticsComprehensive);

            if(resultJO.get("code").toString().equals("1")){
                return R.ok(resultJO);
            }else {
                return R.error(resultJO.get("msg").toString());
            }



        }catch (Exception e){
            logger.error("订单信息获取接口失败,失败原因如下:" + e.getMessage());
            return R.error(e.getMessage());
        }
    }


    //订单创建接口
    @Override
    public R createorder(TccLogisticsComprehensive tccLogisticsComprehensive){
        try {
            //物流渠道
            TccLogisticsChannelDetail tccLogisticsChannelDetail = new TccLogisticsChannelDetail().setLogInvoiceNo(tccLogisticsComprehensive.getLogInvoiceNo()).queryFirst();

            //查询物流服务商
            TccLogisticsServiceProvider tccLogisticsServiceProvider = new TccLogisticsServiceProvider().setProviderBid(tccLogisticsChannelDetail.getProviderCode()).queryFirst();
            if (tccLogisticsServiceProvider == null || tccLogisticsServiceProvider.getAppkey() == null || tccLogisticsServiceProvider.getAppkey().equals("")){
                return R.error("该物流渠道未链接api，无法api下单，请知晓。");
            }

            List<Map<String, Object>> getInfoByCreateOrder = tccLogisticsComprehensiveOrderService.getInfoByCreateOrder(tccLogisticsComprehensive);
            JSONObject jsonObject = getCreateParam(getInfoByCreateOrder,tccLogisticsComprehensive,tccLogisticsServiceProvider,tccLogisticsChannelDetail);
            logger.info("创建订单传参：\n" + jsonObject);
            JSONObject resultJO = getResult(jsonObject,TccLogisticsApiLogEnum.TypeNo.CREATEORDER.value,tccLogisticsServiceProvider,tccLogisticsComprehensive);
            logger.info("创建订单返回：\n" + resultJO);

            //复核、匹配 回传的参数
            if (resultJO.get("code").equals(0)){
                return R.error(resultJO.get("msg").toString());
            }else {

                boolean isSame = true;
                StringBuffer noSameStr = new StringBuffer();

                StringBuffer trackingNumber = new StringBuffer();
                JSONArray data = resultJO.getJSONArray("data");

                JSONObject dataItem = data.getJSONObject(0);
                String packno = dataItem.get("packno").toString();//运单号
                String jcnt = dataItem.get("jcnt").toString();//订单总件数,几箱
                String pmqty = dataItem.get("pmqty").toString();//品名总个数
                String zpqty   = dataItem.get("zpqty").toString();//产品总数量
                String ccvalue = dataItem.get("ccvalue").toString();//总申报价值 =》 采购金额
                String ycz_weit = dataItem.get("ycz_weit").toString();//总实重
                String ysj_weit = dataItem.get("ysj_weit").toString();//总材重
                String ycbm_qty = dataItem.get("ycbm_qty").toString();//总方数
                String orderno = dataItem.get("orderno").toString();//订单号

                for(int i=0;i<data.size();i++){
                    if(data.getJSONObject(i).get("packageResults")!=null){
                        JSONArray packageResults = data.getJSONObject(i).getJSONArray("packageResults");
                        for(int j=0;j<packageResults.size();j++){
                            if(trackingNumber.length()>0){
                                trackingNumber.append(",");
                            }
                            trackingNumber.append(packageResults.getJSONObject(j).getString("trackingNumber"));
                        }
                    }
                }

                //***** 进行匹配、复核 *****
                {
                    //复核 * 运单号
                    if(!tccLogisticsComprehensive.getLogInvoiceNo().equals(packno)){
                        logger.error("运单号未匹配：自身=" + tccLogisticsComprehensive.getLogInvoiceNo()+"；回传="+packno);
                        noSameStr.append("运单号未匹配；");
                        isSame = false;
                    }
                    JSONArray orderDetailList = jsonObject.getJSONObject("data").getJSONArray("orderDetailList");
                    //复核 * 箱子数
                    if(Integer.parseInt(jcnt)!=orderDetailList.size()){
                        noSameStr.append("箱子数未匹配；");
                        logger.error("箱子数未匹配：自身=" + orderDetailList.size()+"；回传="+jcnt);
                        isSame = false;
                    }
                    //自身数据
                    BigDecimal weight_self = BigDecimal.ZERO;//总实重
                    BigDecimal zpqty_self = BigDecimal.ZERO;//产品总数量
                    BigDecimal ccvalue_self = BigDecimal.ZERO;//总申报价值 =》 采购金额
                    BigDecimal ycbm_qty_self = BigDecimal.ZERO;//总方数

                    //根据 品名中午+英文 去重
                    List<Map<String, Object>> listGroupByGoodsName = ToolUtil.groupsByList(getInfoByCreateOrder,e->e.get("nameGoodsCn").toString()+e.get("nameEn").toString());
                    //遍历箱子数据
                    for(int i=0;i<orderDetailList.size();i++){
                        JSONObject orderDetailItem = orderDetailList.getJSONObject(i);
                        weight_self = weight_self.add(orderDetailItem.getBigDecimal("mweit"));
                        ycbm_qty_self = ycbm_qty_self.add(orderDetailItem.getBigDecimal("mlength").multiply(orderDetailItem.getBigDecimal("mwidth")).multiply(orderDetailItem.getBigDecimal("mheight")));
                        JSONArray ordersmatlist = orderDetailItem.getJSONArray("ordersmatlist");
                        //遍历商品数据
                        for(int j=0;j<ordersmatlist.size();j++){
                            JSONObject ordersmatItem = ordersmatlist.getJSONObject(j);
                            //数量
                            zpqty_self = zpqty_self.add(ordersmatItem.getBigDecimal("qty"));
                            //数量 * 采购单价
                            ccvalue_self = ccvalue_self.add(ordersmatItem.getBigDecimal("qty").multiply(ordersmatItem.getBigDecimal("caigouprice")));

                        }
                    }
                    //自身 总材重
                    BigDecimal ysj_weit_self = ycbm_qty_self.divide(new BigDecimal(tccLogisticsChannelDetail.getCoefficientWeight()),2,BigDecimal.ROUND_HALF_UP);
                    //复核 * 产品总数量
                    if(zpqty_self.compareTo(new BigDecimal(zpqty))!=0){
                        logger.error("产品总数量未匹配：自身=" + zpqty_self+"；回传="+zpqty);
                        noSameStr.append("产品总数量未匹配；");
                        isSame = false;
                    }
                    //复核 * 总申报价值 =》 采购金额
                    if((ccvalue_self.setScale(2,BigDecimal.ROUND_HALF_UP)).compareTo((new BigDecimal(ccvalue).setScale(2,BigDecimal.ROUND_HALF_UP)))!=0){
                        logger.error("总申报价值 =》 采购金额未匹配：自身=" + ccvalue_self+"；回传="+ccvalue);
                        noSameStr.append("采购金额未匹配；");
                        isSame = false;
                    }
                    //复核 * 总方数
                    ycbm_qty_self = ycbm_qty_self.divide(new BigDecimal(1000000),2,BigDecimal.ROUND_HALF_UP);
                    if(ycbm_qty_self.compareTo((new BigDecimal(ycbm_qty).setScale(2,BigDecimal.ROUND_HALF_UP)))!=0){
                        logger.error("总方数未匹配：自身=" + ycbm_qty_self+"；回传="+ycbm_qty);
                        noSameStr.append("总方数未匹配；");
                        isSame = false;
                    }
                    //复核 * 总实重
                    if(weight_self.compareTo(new BigDecimal(ycz_weit))!=0){
                        logger.error("总实重未匹配：自身=" + weight_self+"；回传="+ycz_weit);
                        noSameStr.append("总实重未匹配；");
                        isSame = false;
                    }
                    //复核 * 总材重
                    if(ysj_weit_self.compareTo((new BigDecimal(ysj_weit).setScale(2,BigDecimal.ROUND_HALF_UP)))!=0){
                        logger.error("总材重未匹配：自身=" + ysj_weit_self+"；回传="+ysj_weit);
                        noSameStr.append("总材重未匹配；");
                        isSame = false;
                    }
//                    //复核 * 品名总个数
//                    if(Integer.parseInt(pmqty)!=listGroupByGoodsName.size()){
//                        logger.error("品名总个数未匹配：自身=" + listGroupByGoodsName.size()+"；回传="+pmqty);
//                    noSameStr.append("品名总个数未匹配；");
//                        isSame = false;
//                    }
                }




                if(isSame){
                    //修改订单号、API订单号
                    storageMapper.updateOrderNoByLogisticsComprehensive(orderno,tccLogisticsComprehensive.getLogInvoiceNo(), TccLogisticsComprehensiveEnum.ApiPlaceOrderStatus.SUCCESS.value,trackingNumber.toString());
                    return R.ok();
                }else{
                    //修改API状态
                    storageMapper.updateOrderNoByLogisticsComprehensive(orderno,tccLogisticsComprehensive.getLogInvoiceNo(), TccLogisticsComprehensiveEnum.ApiPlaceOrderStatus.NO_FIT.value,trackingNumber.toString());
                    return R.error(noSameStr.toString());
                }

            }


        }catch (Exception e){
            logger.error("订单创建接口失败,失败原因如下:" + e.getMessage(),e);
            return R.error(e.getMessage());
        }



    }

    //获取订单创建需要的参数信息
    private JSONObject getCreateParam(List<Map<String, Object>> dataListBySql,TccLogisticsComprehensive tccLogisticsComprehensive,TccLogisticsServiceProvider tccLogisticsServiceProvider,TccLogisticsChannelDetail tccLogisticsChannelDetail) throws Exception{
        JSONObject res = new JSONObject();




        JSONArray orderDetailList = new JSONArray();


        Map<String, List<Map<String, Object>>> groupsByBoxNo = dataListBySql.stream().collect(Collectors.groupingBy(e->e.get("boxNo").toString()));
        JSONArray fbaWarehouseList = new JSONArray();

        //遍历，填入去重的信息
        groupsByBoxNo.forEach((boxNo, listByBox) -> {
            JSONObject orderDetailListItem = new JSONObject();
            String fbaWarehouse = new String();
            Map<String, Object> boxInfo = listByBox.get(0);

            JSONArray ordersmatlist = new JSONArray();
            for(Map<String, Object> item:listByBox){
                JSONObject ordersmatItem = new JSONObject();
                ordersmatItem.put("jobid",boxNo);//"TESTHWTAPI6543-1",//箱唛号：与上面的jobno一致，可以为单箱上面FBA字号，如果不是FBA货物，有没箱唯一的客户自己的箱唛号，也可以填写，如果实在没有，则填写1，2，3代表第一箱，第二箱，第三箱
                ordersmatItem.put("qty",item.get("fbaBoxDetailNum")!=null?new BigDecimal(item.get("fbaBoxDetailNum").toString()):BigDecimal.ZERO );//单箱产品数量：本箱所装此产品的数量
                ordersmatItem.put("qgbibie",item.get("currencyCode")!=null?item.get("currencyCode").toString():"");//清关申报币种：RMB,USD,GBP等
                ordersmatItem.put("value",item.get("purchaseAmount")!=null?new BigDecimal(item.get("purchaseAmount").toString()):BigDecimal.ZERO);//单个产品清关申报单价
//                ordersmatItem.put("bgbibie","");//报关申报币种：RMB,USD,GBP等  【选填】
//                ordersmatItem.put("bgvalue","");//单个产品报关申报单价  【选填】
                ordersmatItem.put("productch",item.get("nameGoodsCn")!=null?item.get("nameGoodsCn").toString():"");//中文品名
                ordersmatItem.put("producten",item.get("nameEn")!=null?item.get("nameEn").toString():"");//英文品名
//                ordersmatItem.put("pinpai",item.get("brand")!=null?item.get("brand").toString():"");//品牌
                ordersmatItem.put("pinpai","无");//品牌
//                ordersmatItem.put("pptype","03");//品牌类型：调用基础参数接口中的PPTYPE品牌类型获取代号和名称，可以为空   【选填】
                ordersmatItem.put("pptype","无");//品牌类型： 修改代码后直接传中文
                ordersmatItem.put("hscode",item.get("codeGoodsHs")!=null?item.get("codeGoodsHs").toString():"");//国内海关编码
                ordersmatItem.put("forcustno","");//国外海关编码  【选填】
                ordersmatItem.put("xinghao","无");//英文产品型号  【选填】
                ordersmatItem.put("zwarticno","无");//中文产品型号  【选填】
                ordersmatItem.put("caizhi",item.get("materialEn")!=null?item.get("materialEn").toString():"");//英文产品材质
                ordersmatItem.put("zwmat",item.get("nameMaterialCn")!=null?item.get("nameMaterialCn").toString():"");//中文产品材质  【选填】
                ordersmatItem.put("yongtu",item.get("usageEn")!=null?item.get("usageEn").toString():"");//英文产品用途
                ordersmatItem.put("zwuse",item.get("usageCn")!=null?item.get("usageCn").toString():"");//中文产品用途  【选填】
                ordersmatItem.put("baozhuang","");//包装:纸箱或者其他  【选填】
                ordersmatItem.put("jingweit",item.get("weightPackage")!=null?new BigDecimal(item.get("weightPackage").toString()):BigDecimal.ZERO);//单个产品净重
                ordersmatItem.put("daino","");//集运的快递单号  【选填】
                ordersmatItem.put("caigouprice",item.get("purchaseAmount")!=null?new BigDecimal(item.get("purchaseAmount").toString()):BigDecimal.ZERO);//采购单价  【选填】
                ordersmatItem.put("skuno",item.get("sku")!=null?item.get("sku").toString():"");//产品sku码   【选填】
                ordersmatItem.put("salesvalue","");//单个产品销售单价   【选填】
                ordersmatItem.put("salesurl",item.get("linkIn")!=null?item.get("linkIn").toString():"");//产品销售链接   【选填】
                ordersmatItem.put("saveurl",item.get("img")!=null?item.get("img").toString():"");////产品图片下载链接   【选填】
                ordersmatItem.put("picbase64","");//产品图片base64码：建议不要传入，避免资料过大，尽量填写产品图片下载链接   【选填】
                ordersmatItem.put("smatnos","003001");//单个产品性质：如普货，带电，带磁，纺织品等   【选填】 tccLogisticsChannelDetail.getSmatno()
                fbaWarehouse = item.get("fbaWarehouse")!=null?item.get("fbaWarehouse").toString():"";
                ordersmatlist.add(ordersmatItem);
            }
            fbaWarehouseList.add(fbaWarehouse);
            orderDetailListItem.put("zhuangtai","OT");//状态：固定为OT
            orderDetailListItem.put("mlength",boxInfo.get("boxLong")!=null?new BigDecimal(boxInfo.get("boxLong").toString()):BigDecimal.ZERO);//单箱重量尺寸 长
            orderDetailListItem.put("mwidth",boxInfo.get("boxWide")!=null?new BigDecimal(boxInfo.get("boxWide").toString()):BigDecimal.ZERO);//单箱重量尺寸 宽
            orderDetailListItem.put("mheight",boxInfo.get("boxHigh")!=null?new BigDecimal(boxInfo.get("boxHigh").toString()):BigDecimal.ZERO);//单箱重量尺寸 高
            orderDetailListItem.put("mweit",boxInfo.get("boxWeight")!=null?new BigDecimal(boxInfo.get("boxWeight").toString()):BigDecimal.ZERO);//单件实重
            orderDetailListItem.put("jcnt",1);//件数：默认为1
            orderDetailListItem.put("jobno",boxNo);//"TESTHWTAPI6543-1",//箱唛号：可以为单箱上面FBA字号，如果不是FBA货物，有没箱唯一的客户自己的箱唛号，也可以填写，如果实在没有，则填写1，2，3代表第一箱，第二箱，第三箱
            orderDetailListItem.put("refno",boxInfo.get("fbaTrackNo")!=null?boxInfo.get("fbaTrackNo").toString():"");//亚马逊Reference ID  【选填】
            orderDetailListItem.put("ordersmatlist",ordersmatlist);//订单申报要素信息:以下为单箱申报要素信息,可以多个json组合,
            orderDetailList.add(orderDetailListItem);
        });

        Map<String, Object> logInvoiceNoInfo = dataListBySql.get(0);

        JSONObject data = new JSONObject();
        data.put("factno",AESUtil.aesDecrypt(tccLogisticsServiceProvider.getFactno()));
        data.put("supno",AESUtil.aesDecrypt(tccLogisticsServiceProvider.getSupno()));
        data.put("suppass",AESUtil.aesDecrypt(tccLogisticsServiceProvider.getSuppass()));
        data.put("appkey",AESUtil.aesDecrypt(tccLogisticsServiceProvider.getAppkey()));

//        data.put("factno",(tccLogisticsServiceProvider.getFactno()));//企业ID
//        data.put("supno",(tccLogisticsServiceProvider.getSupno()));//客户登录账号
//        data.put("suppass",(tccLogisticsServiceProvider.getSuppass()));//客户登陆密码
//        data.put("appkey",(tccLogisticsServiceProvider.getAppkey()));//客户API授权码
        data.put("organo",tccLogisticsChannelDetail.getStock());//收货仓库代码
        data.put("packno",tccLogisticsComprehensive.getLogInvoiceNo());//运单号 => 物流发票号
        data.put("supcode","");//客户参考号 【选填】
        data.put("typeno","");//主运输类型 【选填】
        data.put("channeltype",tccLogisticsChannelDetail.getValueCode());//渠道类型
        data.put("channelprice","");//价格渠道类型 【选填】
        data.put("worgno",tccLogisticsChannelDetail.getWorgno());//地址类型 => 亚马逊地址
        data.put("addnm", fbaWarehouseList.get(0));//国外地址名称 【选填】
        data.put("dest",tccLogisticsComprehensiveOrderService.getDest(tccLogisticsChannelDetail.getCountry()));//目的地
        data.put("expresstype","");//包裹类型 【选填】 tccLogisticsChannelDetail.getExpresstype()
        data.put("delcompanynm","");//收件人公司名称
        data.put("contactsby","");//收件联系人姓名
        data.put("address1","");//收件人地址1
        data.put("address2","");//收件人地址2 【选填】1的长度若是过长填这
        data.put("address3","");//收件人地址3 【选填】
        data.put("phone","");//收件人电话
        data.put("postno","");//收件人邮编
        data.put("state","");//收件人所在州或者省份 【选填】
        data.put("city","");//收件人城市 【选填】
        data.put("mailNo","");//收件人邮箱 【选填】
        data.put("productname","");//品名 【选填】
        data.put("smatno","003001");//产品大类：如普货，带电，带磁，纺织品
        data.put("bxflg","N");//是否购买保险：需要购买填写Y，不需要填写N
        data.put("indamt",0.00);//保险金额:无需购买保险则填写0.00  【选填】
        data.put("declaration",tccLogisticsChannelDetail.getBaoguan());//报关方式
        data.put("clearance",tccLogisticsChannelDetail.getQingguan());//清关方式
        data.put("yfdfmk","");//预付到付：PP代表预付，CC代表到付，可以为空   【选填】
        data.put("dfdw","");//到付或代收款币种:请填写币种三字码：USD,RMB等    【选填】
        data.put("dfcash","");//到付或代收款金额，可以为空    【选填】
        data.put("remark","");//客户备注    【选填】
        data.put("upsmk","");//快递公司接口类型：如果需要通过api接口直接打UPS或者FEDEX面单则此处必填，否则可以为空，或者默认PACKAGE
        data.put("sendcountry",tccLogisticsChannelDetail.getCountry());//寄件人国家二字码：有条件必填
        data.put("sdcompanynm",logInvoiceNoInfo.get("vgsjc")!=null?logInvoiceNoInfo.get("vgsjc").toString():"");//寄件人公司名：有条件必填
        data.put("sendby",logInvoiceNoInfo.get("companyUser")!=null?logInvoiceNoInfo.get("companyUser").toString():"");//寄件人姓名：有条件必填
        data.put("sendbyaddress",logInvoiceNoInfo.get("addressLine1")!=null?logInvoiceNoInfo.get("addressLine1").toString():"");//寄件人地址1：有条件必填
        data.put("sendmobi",logInvoiceNoInfo.get("phone")!=null?logInvoiceNoInfo.get("phone").toString():"");//寄件人电话：有条件必填
        data.put("sendpostno",logInvoiceNoInfo.get("postalCode")!=null?logInvoiceNoInfo.get("postalCode").toString():"");//寄件人邮编：有条件必填
        data.put("sedprovinces",logInvoiceNoInfo.get("districtOrCounty")!=null?logInvoiceNoInfo.get("districtOrCounty").toString():"");//寄件人省份/州：有条件必填
        data.put("sedcity",logInvoiceNoInfo.get("city")!=null?logInvoiceNoInfo.get("city").toString():"");//寄件人城市：有条件必填
        data.put("sendadd2",logInvoiceNoInfo.get("addressLine2")!=null?logInvoiceNoInfo.get("addressLine2").toString():"");//寄件人地址2：有条件必填
        data.put("sendadd3","");//寄件人地址3：有条件必填
        data.put("sendaddnm","");//寄件人地址名称：有条件必填
//        data.put("sendaddnm",addrName);//寄件人地址名称：有条件必填

        data.put("vatno",logInvoiceNoInfo.get("vat")!=null?logInvoiceNoInfo.get("vat").toString():"");//VAt税号    【选填】
        data.put("eorino",logInvoiceNoInfo.get("eori")!=null?logInvoiceNoInfo.get("eori").toString():"");//欧洲Eori号    【选填】
        data.put("vatfact","");//Vat公司名    【选填】
        data.put("vatadd","");//Vat地址   【选填】
        data.put("vatphone","");//vat电话    【选填】
        data.put("kacheNo","");//卡车预约号    【选填】
        data.put("fbano",logInvoiceNoInfo.get("fbaNo")!=null?logInvoiceNoInfo.get("fbaNo").toString():"");//FBA主单号    【选填】
        data.put("shipmentID","");//ShipmentID    【选填】
        data.put("deliverymode",tccLogisticsChannelDetail.getDeliverymode()!=null&&!"".equals(tccLogisticsChannelDetail.getDeliverymode())?tccLogisticsChannelDetail.getDeliverymode():"");//提货方式    【选填】
        data.put("zycode","");//转单号：一般不用填写   【选填】
        data.put("fileurl1","");//需要提交的文件存储路径1  【选填】
        data.put("fileurl2","");//需要提交的文件存储路径2  【选填】
        data.put("fileurl3","");//需要提交的文件存储路径3  【选填】
        data.put("orderDetailList",orderDetailList);//订单子表信息

        res.put("data",data);
        return res;
    }



    /**
     * 订单取消
     * @return
     */
    @Override
    public R cancelorder(String spOrderBid) {
        try {
            TccLogisticsComprehensive tccLogisticsComprehensive = new TccLogisticsComprehensive().setSpOrderBid(spOrderBid).queryFirst();
            //物流渠道
            TccLogisticsChannelDetail tccLogisticsChannelDetail = new TccLogisticsChannelDetail().setLogInvoiceNo(tccLogisticsComprehensive.getLogInvoiceNo()).queryFirst();
            //查询物流服务商
            TccLogisticsServiceProvider tccLogisticsServiceProvider = new TccLogisticsServiceProvider().setProviderBid(tccLogisticsChannelDetail.getProviderCode()).queryFirst();
            if (tccLogisticsServiceProvider == null || tccLogisticsServiceProvider.getAppkey() == null || "".equals(tccLogisticsServiceProvider.getAppkey())){
                return R.error("该物流渠道未链接api，无法进行api操作，请知晓。");
            }

            JSONObject jsonObject = new JSONObject();
            jsonObject.put("ORDERNO",spOrderBid);//系统订单号
            JSONObject resultJO = getResult(jsonObject,TccLogisticsApiLogEnum.TypeNo.CANCELORDER.value,tccLogisticsServiceProvider,tccLogisticsComprehensive);
            logger.info(spOrderBid+"订单取消返回：\n" + resultJO);
            if(resultJO.get("code").toString().equals("1")){
                return R.ok();
            }else {
                return R.error(resultJO.get("msg").toString());
            }

        }catch (Exception e){
            logger.error("订单取消接口失败,失败原因如下:" + e.getMessage(),e);
            return R.error(e.getMessage());
        }
    }

    /**
     * 标签获取打印
     * @return
     */
    @Override
    public R print(List<String> spOrderBidList) {
        try {
            TccLogisticsComprehensive tccLogisticsComprehensive = new TccLogisticsComprehensive().setSpOrderBid(spOrderBidList.get(0)).queryFirst();
            //物流渠道
            TccLogisticsChannelMaint tccLogisticsChannelMaint = new TccLogisticsChannelMaint().setId(tccLogisticsComprehensive.getLogChannelId()).queryFirst();
            //查询物流服务商
            TccLogisticsServiceProvider tccLogisticsServiceProvider = new TccLogisticsServiceProvider().setProviderBid(tccLogisticsChannelMaint.getProviderCode()).queryFirst();
            if (tccLogisticsServiceProvider == null || tccLogisticsServiceProvider.getAppkey() == null || "".equals(tccLogisticsServiceProvider.getAppkey())){
                return R.error("该物流渠道未链接api，无法进行api操作，请知晓。");
            }

            JSONObject jsonObject = new JSONObject();

//            List<String> ordernoList = new ArrayList<>();
//            ordernoList.add("YD00325030700512");
            jsonObject.put("ORDERNO",spOrderBidList);//系统订单号
            jsonObject.put("TYPENO","NB");//标签类型

            JSONObject resultJO = getResult(jsonObject,TccLogisticsApiLogEnum.TypeNo.PRINT.value,tccLogisticsServiceProvider,tccLogisticsComprehensive);

            //TODO 返回具体打印标签需要的值
            return R.ok(resultJO);
        }catch (Exception e){
            logger.error("标签获取打印接口失败,失败原因如下:" + e.getMessage());
            return R.error(e.getMessage());
        }
    }

    /**
     * 运单轨迹查询
     * @return
     */
    @Override
    public R tracking(List<String> spOrderBidList) {
        try {
            TccLogisticsComprehensive tccLogisticsComprehensive = new TccLogisticsComprehensive().setSpOrderBid(spOrderBidList.get(0)).queryFirst();
            //物流渠道
            TccLogisticsChannelDetail tccLogisticsChannelDetail = new TccLogisticsChannelDetail().setLogInvoiceNo(tccLogisticsComprehensive.getLogInvoiceNo()).queryFirst();
            //查询物流服务商
            TccLogisticsServiceProvider tccLogisticsServiceProvider = new TccLogisticsServiceProvider().setProviderBid(tccLogisticsChannelDetail.getProviderCode()).queryFirst();
            if (tccLogisticsServiceProvider == null || tccLogisticsServiceProvider.getAppkey() == null || "".equals(tccLogisticsServiceProvider.getAppkey())){
                return R.error("该物流渠道未链接api，无法进行api操作，请知晓。");
            }

            JSONObject jsonObject = new JSONObject();


            jsonObject.put("ORDERNO",spOrderBidList);//系统订单号

            JSONObject resultJO = getResult(jsonObject,TccLogisticsApiLogEnum.TypeNo.TRACKING.value,tccLogisticsServiceProvider,tccLogisticsComprehensive);

            return R.ok(resultJO);
        }catch (Exception e){
            logger.error("运单轨迹查询接口失败,失败原因如下:" + e.getMessage(),e);
            return R.error(e.getMessage());
        }
    }

    private JSONObject getResult(JSONObject jsonObject,String uriWithQueryString,TccLogisticsServiceProvider tccLogisticsServiceProvider,TccLogisticsComprehensive tccLogisticsComprehensive)throws Exception{

        jsonObject.put("FACTNO",AESUtil.aesDecrypt(tccLogisticsServiceProvider.getFactno()));
        jsonObject.put("SUPNO",AESUtil.aesDecrypt(tccLogisticsServiceProvider.getSupno()));
        jsonObject.put("SUPPASS",AESUtil.aesDecrypt(tccLogisticsServiceProvider.getSuppass()));
        jsonObject.put("APPKEY",AESUtil.aesDecrypt(tccLogisticsServiceProvider.getAppkey()));

//        jsonObject.put("FACTNO",(tccLogisticsServiceProvider.getFactno()));
//        jsonObject.put("SUPNO",(tccLogisticsServiceProvider.getSupno()));
//        jsonObject.put("SUPPASS",(tccLogisticsServiceProvider.getSuppass()));
//        jsonObject.put("APPKEY",(tccLogisticsServiceProvider.getAppkey()));

        Map<String, String> paramsHerder = new HashMap<String, String>();
        paramsHerder.put("Content-Type", "application/json;charset=UTF-8");
        logger.info("发送参数:\n" + jsonObject);
        String content = JSONObject.toJSONString(jsonObject);

        String result = ApiHttpUtils.sendPostBody(TccLogisticsApiLogEnum.TypeNo.IP.value + uriWithQueryString,
                content, paramsHerder);
        if(result.equals("400")){
            throw new IllegalArgumentException("api下单失败！");
        }
        logger.info("API返回：\n" + result);
        JSONObject resultJO = JSON.parseObject(result);

        //新增日志
        TccLogisticsApiLog tccLogisticsApiLog = TccLogisticsApiLog.tccLogisticsApiLog(
                TccLogisticsApiLogEnum.TypeService.KYT.value,
                TccLogisticsApiLogEnum.TypeNo.getKey(uriWithQueryString),
                tccLogisticsComprehensive!=null?tccLogisticsComprehensive.getLogOrderBid():null,
                tccLogisticsComprehensive!=null?tccLogisticsComprehensive.getLogInvoiceNo():null,
                jsonObject.toJSONString(),
                resultJO.toJSONString(),
                1);
        tccLogisticsApiLogMapper.insert(tccLogisticsApiLog);




        return resultJO;
    }

    /**
     * 获取税金单文件
     * @return
     */
    @Override
    public R getfile(List<String> spOrderBidList) {
        try {
            TccLogisticsComprehensive tccLogisticsComprehensive = new TccLogisticsComprehensive().setSpOrderBid(spOrderBidList.get(0)).queryFirst();
            //物流渠道
            TccLogisticsChannelMaint tccLogisticsChannelMaint = new TccLogisticsChannelMaint().setId(tccLogisticsComprehensive.getLogChannelId()).queryFirst();
            //查询物流服务商
            TccLogisticsServiceProvider tccLogisticsServiceProvider = new TccLogisticsServiceProvider().setProviderBid(tccLogisticsChannelMaint.getProviderCode()).queryFirst();
            if (tccLogisticsServiceProvider == null || tccLogisticsServiceProvider.getAppkey() == null || "".equals(tccLogisticsServiceProvider.getAppkey())){
                return R.error("该物流渠道未链接api，无法进行api操作，请知晓。");
            }

            JSONObject jsonObject = new JSONObject();

            jsonObject.put("ORDERNO",spOrderBidList);//系统订单号
            jsonObject.put("TYPENO","tax");//文件类型

            JSONObject resultJO = getResult(jsonObject,TccLogisticsApiLogEnum.TypeNo.GETFILE.value,tccLogisticsServiceProvider,tccLogisticsComprehensive);

            if(resultJO.get("code").toString().equals("1")){
                return R.ok(resultJO);
            }else {
                return R.error(resultJO.get("msg").toString());
            }



        }catch (Exception e){
            logger.error("获取C88文件接口失败,失败原因如下:" + e.getMessage());
            return R.error(e.getMessage());
        }
    }
}
